package cn.e4j.core.shiro.filters;

import cn.e4j.core.shiro.ShiroKit;
import cn.e4j.core.shiro.ShiroUser;
import cn.e4j.core.shiro.UserPasswordToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import cn.e4j.core.util.HttpContext;
import org.springframework.util.StringUtils;

/**
 * 登录表单验证（包含验证码）过滤类
 *
 * @author wenchuan.li
 * @version 2018/12/03 17:23
 */
@Slf4j
public class AuthcFilter extends FormAuthenticationFilter {

    public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
    public static final String DEFAULT_MOBILE_PARAM = "mobileLogin";
    public static final String DEFAULT_MESSAGE_PARAM = "message";

    private String captchaParam = DEFAULT_CAPTCHA_PARAM;
    private String mobileLoginParam = DEFAULT_MOBILE_PARAM;
    private String messageParam = DEFAULT_MESSAGE_PARAM;

    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
        String username = getUsername(request);
        String password = getPassword(request);
        String lang_ = request.getParameter("lang_");
        String dbc_ = null;
        if (request.getParameter("dbc_") != null) {
            dbc_ = request.getParameter("dbc_").split(" - ")[0];
        }
        String site_ = null;
        if (request.getParameter("site_") != null) {
            site_ = request.getParameter("site_").split(" - ")[0];
        }
        if (password == null) {
            password = "";
        }
//        if (StringUtils.isNotEmpty(password)) {
//            password = AppCodec.password(password);
//        }
        if (lang_ == null) {
            lang_ = "zh_CN";
        }
        boolean rememberMe = isRememberMe(request);
        String host = HttpContext.getIp();
        String captcha = getCaptcha(request);
        boolean mobile = isMobileLogin(request);
        return new UserPasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile,
                lang_, dbc_, site_);
    }

    public String getCaptchaParam() {
        return captchaParam;
    }

    protected String getCaptcha(ServletRequest request) {
        return WebUtils.getCleanParam(request, getCaptchaParam());
    }

    public String getMobileLoginParam() {
        return mobileLoginParam;
    }

    protected boolean isMobileLogin(ServletRequest request) {
        return WebUtils.isTrue(request, getMobileLoginParam());
    }

    public String getMessageParam() {
        return messageParam;
    }

    /**
     * 登录成功之后跳转URL
     */
    public String getSuccessUrl() {
        return super.getSuccessUrl();
    }

    @Override
    protected void issueSuccessRedirect(ServletRequest request,
                                        ServletResponse response) throws Exception {

        ShiroUser shiroUser = ShiroKit.getUser();
        //  && !p.isMobileLogin()
        if (shiroUser != null) {
            WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
        }
        /*else{
            logger.debug(AppCons.CONSOLE_FLAG3+"手机登录认证");
			super.issueSuccessRedirect(request, response);//手机登录 todo
		}*/
    }

    /**
     * 登录失败调用事件
     */
    @Override
    protected boolean onLoginFailure(AuthenticationToken token,
                                     AuthenticationException e, ServletRequest request, ServletResponse response) {
        String className = e.getClass().getName(), message = "";
        if (IncorrectCredentialsException.class.getName().equals(className)
                || UnknownAccountException.class.getName().equals(className)) {
            message = "用户或密码错误, 请重试.";
        } else if (e.getMessage() != null && StringUtils.startsWithIgnoreCase(e.getMessage(), "msg:")) {
            message = StringUtils.replace(e.getMessage(), "msg:", "");
        } else {
            message = "系统出现问题，请稍后再试！";
            e.printStackTrace(); // 输出到控制台
        }
        request.setAttribute(getFailureKeyAttribute(), className);
        request.setAttribute(getMessageParam(), message);
        return true;
    }

}